import { Op } from 'sequelize';
import User from '@/models/User.model';
import { UserStatus, UserType, PaginatedResult } from '@/types';
import { getPaginationParams } from '@/utils/helpers';
import logger from '@/utils/logger';
import AuditLog from '@/models/AuditLog.model';
import { AuditAction } from '@/types';

interface CreateUserData {
  tenantId: string | null;
  email: string;
  password: string;
  firstName?: string;
  lastName?: string;
  type?: UserType;
  roleId?: string;
}

interface UpdateUserData {
  email?: string;
  firstName?: string;
  lastName?: string;
  roleId?: string;
  status?: UserStatus;
  avatar?: string;
}

interface ListUsersFilter {
  tenantId?: string;
  type?: UserType;
  status?: UserStatus;
  search?: string;
  page?: number;
  pageSize?: number;
}

/**
 * 用户服务
 */
export class UserService {
  /**
   * 创建用户
   */
  async createUser(data: CreateUserData, creatorId?: string): Promise<User> {
    // 检查邮箱是否已存在（同一租户内）
    const whereClause: any = { email: data.email };
    if (data.tenantId) {
      whereClause.tenantId = data.tenantId;
    }

    const existingUser = await User.findOne({ where: whereClause });

    if (existingUser) {
      throw new Error('邮箱已被使用');
    }

    // 创建用户
    const user = await User.create({
      ...data,
      type: data.type || UserType.TENANT_USER,
      status: UserStatus.ACTIVE,
    });

    // 记录审计日志
    if (creatorId) {
      await AuditLog.create({
        tenantId: data.tenantId,
        userId: creatorId,
        action: AuditAction.CREATE,
        resource: 'user',
        resourceId: user.id,
        changes: { email: data.email },
      });
    }

    logger.info(`创建用户成功: ${user.email} (${user.id})`);

    return user;
  }

  /**
   * 获取用户详情
   */
  async getUserById(id: string): Promise<User | null> {
    return User.findByPk(id, {
      include: [
        {
          association: 'role',
          attributes: ['id', 'name'],
        },
        {
          association: 'department',
          attributes: ['id', 'name'],
        },
      ],
    });
  }

  /**
   * 获取用户列表
   */
  async listUsers(filter: ListUsersFilter): Promise<PaginatedResult<User>> {
    const {
      page = 1,
      pageSize = 20,
      tenantId,
      type,
      status,
      search,
    } = filter;

    const pagination = getPaginationParams(page, pageSize);

    const whereClause: any = {};

    if (tenantId) {
      whereClause.tenantId = tenantId;
    }

    if (type) {
      whereClause.type = type;
    }

    if (status) {
      whereClause.status = status;
    }

    if (search) {
      whereClause[Op.or] = [
        { email: { [Op.iLike]: `%${search}%` } },
        { firstName: { [Op.iLike]: `%${search}%` } },
        { lastName: { [Op.iLike]: `%${search}%` } },
      ];
    }

    const { count, rows } = await User.findAndCountAll({
      where: whereClause,
      offset: pagination.offset,
      limit: pagination.limit,
      order: [['createdAt', 'DESC']],
      include: [
        {
          association: 'role',
          attributes: ['id', 'name'],
        },
        {
          association: 'department',
          attributes: ['id', 'name'],
        },
      ],
    });

    return {
      data: rows.map((user) => user.toSafeObject()),
      pagination: {
        total: count,
        page: pagination.page,
        pageSize: pagination.pageSize,
        totalPages: Math.ceil(count / pagination.pageSize),
      },
    };
  }

  /**
   * 更新用户
   */
  async updateUser(
    id: string,
    data: UpdateUserData,
    updaterId?: string,
  ): Promise<User> {
    const user = await User.findByPk(id);

    if (!user) {
      throw new Error('用户不存在');
    }

    // 如果更新邮箱，检查是否已存在
    if (data.email && data.email !== user.email) {
      const whereClause: any = { email: data.email };
      if (user.tenantId) {
        whereClause.tenantId = user.tenantId;
      }

      const existingUser = await User.findOne({ where: whereClause });

      if (existingUser) {
        throw new Error('邮箱已被使用');
      }
    }

    const oldData = user.toJSON();
    await user.update(data);

    // 记录审计日志
    if (updaterId) {
      await AuditLog.create({
        tenantId: user.tenantId,
        userId: updaterId,
        action: AuditAction.UPDATE,
        resource: 'user',
        resourceId: user.id,
        changes: { before: oldData, after: data },
      });
    }

    logger.info(`更新用户: ${user.email} (${user.id})`);

    return user;
  }

  /**
   * 激活用户
   */
  async activateUser(id: string, updaterId?: string): Promise<User> {
    const user = await this.updateUser(
      id,
      { status: UserStatus.ACTIVE },
      updaterId,
    );

    await AuditLog.create({
      tenantId: user.tenantId,
      userId: updaterId || user.id,
      action: AuditAction.ACTIVATE,
      resource: 'user',
      resourceId: user.id,
    });

    return user;
  }

  /**
   * 禁用用户
   */
  async deactivateUser(id: string, updaterId?: string): Promise<User> {
    const user = await this.updateUser(
      id,
      { status: UserStatus.INACTIVE },
      updaterId,
    );

    await AuditLog.create({
      tenantId: user.tenantId,
      userId: updaterId || user.id,
      action: AuditAction.DEACTIVATE,
      resource: 'user',
      resourceId: user.id,
    });

    return user;
  }

  /**
   * 删除用户（软删除）
   */
  async deleteUser(id: string, deleterId?: string): Promise<void> {
    const user = await User.findByPk(id);

    if (!user) {
      throw new Error('用户不存在');
    }

    await user.destroy();

    // 记录审计日志
    if (deleterId) {
      await AuditLog.create({
        tenantId: user.tenantId,
        userId: deleterId,
        action: AuditAction.DELETE,
        resource: 'user',
        resourceId: user.id,
      });
    }

    logger.info(`删除用户: ${user.email} (${user.id})`);
  }

  /**
   * 为用户分配角色
   */
  async assignRole(userId: string, roleId: string, assignerId?: string): Promise<User> {
    return this.updateUser(userId, { roleId }, assignerId);
  }
}

export default new UserService();

